package com.grasp.forrobchance.services;

import android.accessibilityservice.AccessibilityService;
import android.annotation.SuppressLint;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;

import com.rooten.AppHandler;
import com.rooten.interf.IHandler;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import lib.grasp.util.L;
import lib.grasp.util.SPUtil;
import lib.grasp.util.TOAST;
import lib.grasp.widget.MessageBoxGrasp;

@SuppressLint("NewApi")
public class MyAccessibility extends AccessibilityService implements IHandler {

    private static final String TAG                                         = "MyAccessibilityService";
//    private static final String PAGE_ActivityHome                           ="cn.newugo.app.home.activity.ActivityHome";
    /** 课程列表 */
    private static final String TAG_ActivityGroupCourseList                 = "cn.newugo.app.order.activity.ActivityGroupCourseList";
    /** 课程详情界面 */
    private static final String TAG_ActivityGroupCourseOrderDetail          = "cn.newugo.app.order.activity.ActivityGroupCourseOrderDetail";
    /** 预约扣费界面 */
    private static final String TAG_Order                                   = "cn.newugo.app.order.activity.ActivityGroupCourseOrder";
    private static final String LISTEN_PACKAGENAME                          = "cn.newugo.app";

    public static int HOUR1 = 12;
    public static int HOUR2 = 13;
    public static int MINUTE1 = 30;
    public static int MINUTE2 = 30;
    public static int SECOND1 = 5;
    public static int SECOND2 = 5;

    private AppHandler mHandler    = new AppHandler(this);

    /** 开始【时间轮询】，但发现当前距离【活动开始时间】较远 */
    private int MSG_CODE_ACTIVITY_NOT_YET = -102;

    /** 允许开始【时间轮询】的（提前）时延（分钟） */
    private int TIME_AHEAD_TO_TIKTOK = 5;

    /** 时间轮询的间隔（毫秒），默认50 */
    private int TIME_LOOP_INTERVAL = 50;

    /** 活动开始后，延迟进活动页面（毫秒），因为服务器的时间、手机时间、真实时间三者并不统一,默认750 */
    public static int TIME_TO_DELAY = 750;

    /** 活动开始后，在抢票页面的切换延时（毫秒），因为各手机的性能差距，存在页面切换延时，默认10 */
    private int TIME_DELAY_4_PAGE_SWITCH = 10;

    public static String TAG_TIME_LOOP_INTERVAL = "TAG_TIME_LOOP_INTERVAL";
    public static String TAG_TIME_TO_DELAY = "TAG_TIME_TO_DELAY";
    public static String TAG_TIME_DELAY_4_PAGE_SWITCH = "TAG_TIME_DELAY_4_PAGE_SWITCH";

    /**
     * 主页的AccessibilityEvent
     */
    private AccessibilityEvent mEvent;

    /**
     * 计时器
     */
    private Timer mTimer;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        Log.e(TAG, "MyAccessibilityService onDestroy");
        if(mTimer != null) {
            try{
                mTimer.cancel();
            }
            catch (Exception ignored){}
        }

        super.onDestroy();
    }

    //服务连接成功时的回调
    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();
        Log.e(TAG, "MyAccessibilityService onServiceConnected");

        TIME_LOOP_INTERVAL          = SPUtil.getInt(MyAccessibility.TAG_TIME_LOOP_INTERVAL,          50);
        TIME_TO_DELAY               = SPUtil.getInt(MyAccessibility.TAG_TIME_TO_DELAY,               750);
        TIME_DELAY_4_PAGE_SWITCH    = SPUtil.getInt(MyAccessibility.TAG_TIME_DELAY_4_PAGE_SWITCH,    10);

        Log.e(TAG, "-------参数1：" + TIME_LOOP_INTERVAL);
        Log.e(TAG, "-------参数2：" + TIME_TO_DELAY);
        Log.e(TAG, "-------参数3：" + TIME_DELAY_4_PAGE_SWITCH);
//        TOAST.showShort("-------参数：" + TIME_LOOP_INTERVAL + "，" + TIME_TO_DELAY + "，" + TIME_DELAY_4_PAGE_SWITCH);

        if(!isAllowToTiktok()) {
            TOAST.showShort("请在开抢之前" + TIME_AHEAD_TO_TIKTOK + "分钟之内开启【无障碍功能】");
            return;
        }
        startClocking();
        TOAST.showShort("服务成功开启，请打开微健APP，并进入指定页面");
    }

    //接收到系统发送AccessibilityEvent时的回调
    @Override
    public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
        Log.e(TAG, "MyAccessibilityService onAccessibilityEvent: " + accessibilityEvent);
        String packageName = accessibilityEvent.getPackageName().toString();
        if (LISTEN_PACKAGENAME.equals(packageName)){
            Log.e(TAG, "MyAccessibilityService packageName true");
            int eventType = accessibilityEvent.getEventType();
            switch (eventType){
                case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED:
                    Log.e(TAG, "MyAccessibilityService TYPE_VIEW_ACCESSIBILITY_FOCUSED");
                    break;
                case AccessibilityEvent.TYPE_VIEW_CLICKED:
                    Log.e(TAG, "MyAccessibilityService TYPE_VIEW_CLICKED");
                    break;
                case AccessibilityEvent.TYPE_VIEW_FOCUSED:
                    Log.e(TAG, "MyAccessibilityService TYPE_VIEW_FOCUSED");
                    break;
                case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED:
                    Log.e(TAG, "MyAccessibilityService TYPE_VIEW_TEXT_CHANGED");
                    break;
                case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:
                    Log.e(TAG, "MyAccessibilityService TYPE_WINDOW_CONTENT_CHANGED");
                    if(accessibilityEvent.getContentChangeTypes() != (AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE + AccessibilityEvent.CONTENT_CHANGE_TYPE_TEXT)) break;
                    onWINDOW_CONTENT_CHANGED();
                    break;
                case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:  // 页面跳转, 回调参数为当前页面显示的Activity（跳转之后）
                    mEvent = accessibilityEvent; // 记录当前页面的event
                    onActivityStatusChanged();
                    try {
                        Log.e(TAG, "MyAccessibilityService TYPE_WINDOW_STATE_CHANGED");
                    } catch (Exception e) {
                        e.printStackTrace();
                        Log.e(TAG, e.getMessage());
                    }
                    break;
            }
        }else{
            Log.e(TAG, "MyAccessibilityService packageName error: " + packageName);
        }
    }

    /**
         * 页面内容发生变换（页面渲染回调）
         */
    @SuppressLint("WrongConstant")
    private void onWINDOW_CONTENT_CHANGED(){
        Log.e(TAG, "-------页面内容发生切换");  // ActivityHome
        // 当页面发生跳转之后，晚点再执行
        if(mEvent == null) return;
        String className = mEvent.getClassName().toString();
        switch (className) {    // 当前哪个页面的内容发生了变化
            case TAG_ActivityGroupCourseOrderDetail: { // 【课程详情】界面
                Log.e(TAG, "【课程详情】数据已更新");
                performClickFirstBtnByBtnRegex(mEvent, "立即预约", 0, false, false);
                break;
            }

//            case PAGE_ActivityHome:// 主页
            case TAG_ActivityGroupCourseList:// [课程表]界面
            case TAG_Order: {
                // 【预约扣费】界面
                break;
            }
        }
    }


    /**
     * 当前页面已经跳转到
     */
    private void onActivityStatusChanged(){
        Log.e(TAG, "-------页面发生切换");  // ActivityHome
        // 当页面发生跳转之后，晚点再执行
        if(mEvent == null) return;
        String className = mEvent.getClassName().toString();
        switch (className) {    // 当前在那个页面
//            case PAGE_ActivityHome: {
//                // 跳转进入 - 主页
//                mHandler.sendMessageDelayed(new Message(), 500);
//                break;
//            }

            case TAG_ActivityGroupCourseList: {
                // 跳转进入 - [课程表]界面
                mHandler.sendMessageDelayed(new Message(), 50); // 这里50毫秒因为这里是进入页面之后才有数据请求，二之后的页面都没有数据请求，只有数据渲染
                break;
            }

            case TAG_ActivityGroupCourseOrderDetail: {
                // 跳转进入 - 【课程详情】界面
                mHandler.sendMessageDelayed(new Message(), TIME_DELAY_4_PAGE_SWITCH);
                break;
            }

            case TAG_Order: {
                // 跳转进入 - 【预约扣费】界面
                mHandler.sendMessageDelayed(new Message(), TIME_DELAY_4_PAGE_SWITCH);
                break;
            }
        }
    }

    @Override
    public boolean handleMessage(Message msg) {
        Log.e(TAG, "-------收到消息");
        if(msg == null) {
            Log.e(TAG, "-------消息内容丢失");
            return true;
        }
        if(msg.what == MSG_CODE_ACTIVITY_NOT_YET){
//            TOAST.showShort("未到开抢时间，请先关闭【无障碍】，并于活动开始前【2分钟】开启");
            Log.e(TAG, "-------未到开抢时间，请先关闭【无障碍】，并于活动开始前【2分钟】开启");
            return true;
        }

        if(mEvent == null) return true;
        if(mEvent.getClassName() == null) return true;
        String className = mEvent.getClassName().toString();
        switch (className) {    // 当前在那个页面
//            case PAGE_ActivityHome: {
//                // 跳转进入 - 主页
//                Log.e(TAG, "已跳转进入 - 【主页】");
//                performClickFirstBtnByBtnRegex(mEvent, "课程表", 0, false, false);
//                break;
//            }

            case TAG_ActivityGroupCourseList: {
                // 跳转进入 - [课程表]界面
                Log.e(TAG, "已跳转进入 - 【课程表界面】");
                if(Calendar.getInstance().get(Calendar.HOUR_OF_DAY) == HOUR1){
                    // 12:30开抢18:30的座位
                    performClickFirstBtnByBtnRegex(mEvent, "动感单车", 0, false, false);
                }
                else if(Calendar.getInstance().get(Calendar.HOUR_OF_DAY) == HOUR2){
                    // 13:30开抢19:30的座位
                    performClickFirstBtnByBtnRegex(mEvent, "动感单车", 1, false, false);
                }
                else{
                    Log.e(TAG, "当前时间很尴尬，不知道要抢那个点的动感单车，所以不抢");
                }

                break;
            }

            case TAG_ActivityGroupCourseOrderDetail: {
                // 跳转进入 - 【课程详情】界面
                Log.e(TAG, "已跳转进入 - 【课程详情】");
                // *** 这里不要立刻点击“立即预约”按钮，因为有可能页面还没有渲染出来(该页面就没有该按钮)，在页面渲染回调事件中（渲染回调之后）模拟点击该按钮
//                performClickFirstBtnByBtnRegex(mEvent, "立即预约", 0, false, false);
                break;
            }

            case TAG_Order: {
                // 跳转进入 - 【预约扣费】界面
                Log.e(TAG, "已跳转进入 - 【预约扣费】");
                performClickFirstBtnByBtnRegex(mEvent, "1", 0, false, false); // 选号界面排除第一个
                break;
            }

        }

        return false;
    }

    /**
     * 模拟点击页面中指定名称的第N个的按钮
     * @param accessibilityEvent
     * @param regex
     * @param index 从0开始
     * @param isUseId 是否通过ID来寻找控件 例如 cn.newugo.app:id/lay_club_joined_list_footer_qr_code
     */
    private void performClickFirstBtnByBtnRegex(AccessibilityEvent accessibilityEvent, String regex, int index, boolean isUseId, boolean isJustConfirm){
        if(!justiceIfAuto()) {
            Log.e(TAG, "没到时间，不自动跳转");
            return;       // 没到时间不自动跳转
        }
        if(TextUtils.isEmpty(regex)) {
            Log.e(TAG, "指定按钮名称为空，请检查");
            return;
        }
        AccessibilityNodeInfo ani = accessibilityEvent.getSource();

        List<AccessibilityNodeInfo> anis;
        if (ani == null) return;
        if (isUseId){
            anis = ani.findAccessibilityNodeInfosByViewId(regex);
        }
        else{
            anis = ani.findAccessibilityNodeInfosByText(regex);
        }

        if(anis == null || anis.size() < index + 1){
            Log.e(TAG, "-------未找到指定名称名称的控件：" + regex);
            if(TextUtils.equals(regex, "立即预约")){
                // 获取UiDevice实例
                performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
                Log.e(TAG, "-------活动未开始，赶紧返回");
            }
            return;
        }

        String className = accessibilityEvent.getClassName().toString();
        if(TextUtils.equals(regex, "课程表") || TextUtils.equals(regex, "动感单车")){
            if(anis.get(index) == null){
                return;
            }
            anis.get(index).getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK);
        }
        else if(TextUtils.equals(className, TAG_Order)){ // 具体选号界面
            if(!isJustConfirm){
                // 来选号
                int childCount = anis.get(index).getParent().getChildCount();
                boolean existItemCanBook = false;
                for(int i = 7; i < childCount; i++){
                    if(!anis.get(index).getParent().getChild(i).isClickable()) continue;
                    anis.get(index).getParent().getChild(i).performAction(AccessibilityNodeInfo.ACTION_CLICK);
                    existItemCanBook = true;
                    Log.e(TAG, "-------已选定号码：" + anis.get(index).getParent().getChild(i).getText());
                    break;
                }
                if(!existItemCanBook){
                    Log.e(TAG, "-------本页面未发现可以预约的项目");
                }
                // 选择号码成功，去点击【确认预约】按钮
                Log.e(TAG, "-------模拟点击【确认预约】");
                performClickFirstBtnByBtnRegex(accessibilityEvent, "确认预约", 1, false, true);
            }
            else{
                // 选完号点击[确认预约]
                anis.get(index).performAction(AccessibilityNodeInfo.ACTION_CLICK);
                Log.e(TAG, "-------已确认预约");
            }
        }
        else{
            // 立即预约
            anis.get(index).performAction(AccessibilityNodeInfo.ACTION_CLICK);
        }
        Log.e(TAG, "-------模拟点击成功：" + regex);
    }



    //服务中断时的回调
    @Override
    public void onInterrupt() {
        Log.e(TAG, "MyAccessibilityService onInterrupt");
    }

    /**
     * 添加一个本地计时器<br/>
     * 代码计时器，在到达时间后【触发一次】
     */
    private void startClocking(){
        if(mTimer != null) mTimer.cancel();
        TimerTask timeTask = new TimerTask()
        {
            @Override
            public void run()
            {
                // 开始计时
                if(!justiceIfAuto()) {
                    mHandler.sendEmptyMessage(MSG_CODE_ACTIVITY_NOT_YET);
                    return;
                }
                Log.e(TAG, "-------时间到了，发通知， 判断【mEvent == null】：" + (mEvent == null));
                mHandler.sendMessageDelayed(new Message(), TIME_TO_DELAY); // 延迟去进页面，标准值：750
                if(mTimer != null) mTimer.cancel();
            }
        };
        mTimer = new Timer();
        mTimer.schedule(timeTask, 500, TIME_LOOP_INTERVAL);
    }

    /**
     * 以当前时间判断是否能去实现【自动预约】
     */
    private boolean justiceIfAuto(){
        int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
        int minute = Calendar.getInstance().get(Calendar.MINUTE);
        int second = Calendar.getInstance().get(Calendar.SECOND);
        if(hour == HOUR1 && minute == MINUTE1 && second <= SECOND1){    // 这里只有在12:30:00到12:30:05之间才会去抢
            return true;
        }
        else if(hour == HOUR2 && minute == MINUTE2 && second <= SECOND2){    // 这里只有在13:30:00到13:30:05之间才会去抢
            return true;
        }
        Log.e(TAG, "-------当前手机时间：" + hour + ", " + minute + ", " + second);
        Log.e(TAG, "-------时间【太早或者太晚】，所以不抢");
        return false; // 这里为false则代表只在开抢后一定时间范围内【自动预约】，为true则代表全天干预用户操作
    }

    /**
     * 检查当前时间能否开启【倒计时轮询】
     */
    private boolean isAllowToTiktok(){
//        Calendar now = Calendar.getInstance();
//        Calendar time1 = Calendar.getInstance();
//        time1.set(Calendar.getInstance().get(Calendar.YEAR),
//                Calendar.getInstance().get(Calendar.MONTH),
//                Calendar.getInstance().get(Calendar.DAY_OF_MONTH),
//                HOUR1, MINUTE1); // 结束时间
//
//        long minutesDiff = (time1.getTimeInMillis() - now.getTimeInMillis()) / (60 * 1000);
//
//
        int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
        int minute = Calendar.getInstance().get(Calendar.MINUTE);
        int second = Calendar.getInstance().get(Calendar.SECOND);
        if(hour == HOUR1 && minute >= (MINUTE1 - TIME_AHEAD_TO_TIKTOK) && minute < MINUTE1){    // 只有开抢之前5分钟才能开启【倒计时轮询】
            return true;
        }
        else if(hour == HOUR2 && minute >= (MINUTE2 - TIME_AHEAD_TO_TIKTOK) && minute < MINUTE2){     // 只有开抢之前5分钟才能开启【倒计时轮询】
            return true;
        }
        Log.e(TAG, "-------时间【太早或者太晚】，所以不开启轮询");
        return false; // 这里为false则代表只在开抢后一定时间范围内【自动预约】，为true则代表全天干预用户操作
    }

}
